use chrono::Local;
use sqlite_wasm_rs::sqlite3_stmt;
use crate::db::db::{Db, DbParamType};
use crate::db::pojo::pojo::{ImSetting};
use crate::db::util::{db_get_int64, db_get_string};
use crate::util::time::parse_to_time;

pub fn setting_insert(db: Db, setting: &mut ImSetting) {
    let sql = "insert into im_setting(currentUserId, name, value, description, ext1, ext2, createTime, updateTime) values(?, ?, ?, ?, ?, ?, ?, ?)";

    let mut params = vec![];
    params.push(DbParamType::Str(&*setting.current_user_id));
    params.push(DbParamType::Str(&*setting.name));
    params.push(DbParamType::Str(&*setting.value));
    params.push(DbParamType::OptionStr(setting.description.as_ref()));
    params.push(DbParamType::OptionStr(setting.ext1.as_ref()));
    params.push(DbParamType::OptionStr(setting.ext2.as_ref()));
    params.push(DbParamType::DateTime2(&setting.create_time));
    params.push(DbParamType::DateTime2(&setting.update_time));

    let id = db.insert("setting insert", sql, params);
    setting.id = Some(id);
}

pub fn setting_update(db: Db, setting: &mut ImSetting) {
    let sql = "update im_setting set value = ?, description = ?, ext1 = ?, ext2 = ?, updateTime = ? where currentUserId = ? and name = ?";

    let mut params = vec![];
    setting.update_time = Local::now();
    
    params.push(DbParamType::Str(&*setting.value));
    params.push(DbParamType::OptionStr(setting.description.as_ref()));
    params.push(DbParamType::OptionStr(setting.ext1.as_ref()));
    params.push(DbParamType::OptionStr(setting.ext2.as_ref()));
    params.push(DbParamType::DateTime2(&setting.update_time));

    params.push(DbParamType::Str(&*setting.current_user_id));
    params.push(DbParamType::Str(&setting.name));

    db.exec2("setting update", sql.to_string(), params);
}

pub fn setting_query_by_name(db: Db, current_user_id: &String, name: &'static str)->Option<ImSetting> {
    let sql = "select id, currentUserId, name, value, description, ext1, ext2, createTime, updateTime from im_setting where currentUserId = ? and name = ?";
    let mut params = vec![];
    params.push(DbParamType::Str(current_user_id));
    params.push(DbParamType::Str(name));
    db.query_one("setting query", sql.to_string(), params, Box::new(setting_wrap))
}

fn setting_wrap(stmt: *mut sqlite3_stmt)-> ImSetting {
    unsafe {
        let id = db_get_int64(stmt, 0);
        let current_user_id = db_get_string(stmt, 1).unwrap();
        let name = db_get_string(stmt, 2).unwrap();
        let value = db_get_string(stmt, 3).unwrap();
        let description = db_get_string(stmt, 4);
        let ext1 = db_get_string(stmt, 5);
        let ext2 = db_get_string(stmt, 6);
        let create_time_str = db_get_string(stmt, 7).unwrap();
        let update_time_str = db_get_string(stmt, 8).unwrap();

        ImSetting {
            id: Some(id),
            name,
            current_user_id,
            value,
            description,
            ext1,
            ext2,
            create_time: parse_to_time(create_time_str),
            update_time: parse_to_time(update_time_str),
        }
    }
}